package vic.controller;

import java.util.HashMap;
import java.util.List;

import vic.constdefinition.Config;
import vic.extension.VicExtension;
import vic.logic.Board;
import vic.logic.GameModuleLogic;
import vic.sendreceive.command.BaseCommandDefinition;
import vic.sendreceive.param.PlayBoardParamDefinition;
import vic.sendreceive.utilities.GamePackage;





import com.smartfoxserver.v2.api.CreateRoomSettings;
import com.smartfoxserver.v2.entities.Room;
import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSObject;
import com.smartfoxserver.v2.exceptions.SFSCreateRoomException;


public class GameRoomController  extends IRoomController{
	public HashMap<Integer, Playboard>	playBoards;
	public HashMap<Integer, Board>	boards;
	public LobbyRoom lobbyBoard;	
	
	public GameRoomController(){
		playBoards = new HashMap<Integer, Playboard>();
		boards = new HashMap<Integer, Board>();
		System.out.println("GameRoomController --> init playBoards");
	}
	
	public void handleClientRequest(String cmd, User sender, ISFSObject params) {
		
		switch (cmd) 
		{
			case BaseCommandDefinition.requestCreateRoom:
				requestJoinRoom(sender, params);
				break;
			case BaseCommandDefinition.requestCreateBoard:
				createBoard(sender, params);
				break;	
			case BaseCommandDefinition.requestMoveItem:
				moveItem(sender, params);
				break;	
			case BaseCommandDefinition.requestCheckAllItems:
				checkAllItems(sender, params);
				break;	
			default:
				break;
		}
		
		/*
		GamePackage gp = new GamePackage(params);
		String requestCmd = gp.getCommand();
		Room room = sender.getLastJoinedRoom(); 
		if(room != null){
			Playboard playboard = this.getPlayboard(room.getId());
			if(gp.getCommand().equals(BattleCommandDefinition.startGame)){
				this.startGame(sender,playboard);
				return;
			}else if(playboard != null && playboard.isPlaying){
				playboard.iLogic.handleRequest(gp, sender);
				return;
			}
		}
		if(requestCmd.equalsIgnoreCase(BattleCommandDefinition.requestJoinRoom)){
			requestJoinRoom(sender);
		}
		*/
	}
	private Playboard createPlayboard(User sender, ISFSObject params){
		Playboard playboard = null;
		Room room = null;
		String roomName = params.getUtfString(PlayBoardParamDefinition.playboardName);
		CreateRoomSettings roomSetting = new CreateRoomSettings();
		roomSetting.setMaxUsers(Config.playboardMaxPlayer);
		roomSetting.setMaxSpectators(Config.playboardMaxSpec);
		if(roomName == "")
			roomSetting.setName(Config.playboardRoomName + sender.getId());
		else
			roomSetting.setName(roomName);
		roomSetting.setDynamic(false);
		roomSetting.setGame(true);
		roomSetting.setPassword("");
		try {
			room = currentZone.createRoom(roomSetting, sender);
			GameModuleLogic gameLogic = new GameModuleLogic();
			playboard = new Playboard(room, sender, gameLogic);
			// this.playBoards.put(playboard.room.getId(), playboard);
			this.playBoards.put(1, playboard);	// VH TEST
			
		} catch (SFSCreateRoomException e) {
			e.printStackTrace();
		}
		gameExtension.send(BaseCommandDefinition.responseCreateRoom, playboard.packAndSend(), sender);
		return playboard;
	}
	
	public void setExtension(VicExtension sfsExtension){
		this.gameExtension = sfsExtension;
		this.currentZone = sfsExtension.getParentZone();
	}
//	@Override
//    public void handleServerEvent(ISFSEvent event) throws SFSException{
//		User user = (User) event.getParameter(SFSEventParam.USER);
//         System.out.println("user disconnect "+ user.getId());
//         GameRoomController.handleUserDisconnect();
//    }
//	public static void handleUserDisconnect(){
//		System.out.println("user disconnect "+ gameModel);
//		gameModel.checkStopGame();
//	}
	
	public void sendPrivate(User receive, GamePackage gp){		
		gameExtension.send(BaseCommandDefinition.resClientRequest, gp.packCommand(), receive);
	}
	
	@Override
	public void sendAllInRoom(GamePackage gp,Room room){		
		List<User> playerList = room.getPlayersList();
		int len = playerList.size();		
		for(int i = 0; i < len; i++){			
			sendPrivate(playerList.get(i), gp);			
		}
		playerList = null;
	}
	public void sendOtherInRoom(GamePackage gp,Room room, User sfsUser){
		List<User> playerList = room.getPlayersList();
		int len = playerList.size();		
		for(int i = 0; i < len; i++){
			if(sfsUser.getId() != playerList.get(i).getId())
				sendPrivate(playerList.get(i), gp);
		}
		playerList = null;
	}	
	public Playboard getAvailableRoom(User user){
		for(Playboard playboard : playBoards.values()){
			if(!playboard.isPlaying){
				return playboard;
			}
		}
		return null;
	}
	private void requestJoinRoom(User sender, ISFSObject params){
		System.out.println("requestJoinRoom");
		//Playboard  playboard  = this.getAvailableRoom(sender);
		Playboard  playboard  = this.playBoards.get(1);	// VH TEST
		
		if(playboard != null)
			playboard.joinPlayboard(sender);
		else
			playboard = this.createPlayboard(sender, params);
		if(playboard.room.getPlayersList().size() == Config.maxUser)
			startGame(sender,playboard);
	}
	private void startGame(User sender, Playboard playboard) {
		if(!playboard.isPlaying){
			playboard.isPlaying = true;
			Room room = sender.getLastJoinedRoom();
		}
	}
	private Playboard getPlayboard(int id) {
		return playBoards.get(id);
	}
	
	private void createBoard(User sender, ISFSObject params){
		Board board = new Board();
		boards.put(1, board);		
		
		ISFSObject resObj = SFSObject.newInstance();
		
		resObj.putUtfString("itemListString", board.itemListToString());
		
		// gameExtension.send(BaseCommandDefinition.responseCreateBoard, resObj, sender);
		
		//// VH TEST
		Room room = sender.getLastJoinedRoom();
		List<User> userList = room.getPlayersList();
		for(int i=0; i < userList.size(); i++)
		{
			if(userList.get(i) == sender)
				resObj.putBool("is_turn", true);
			else
				resObj.putBool("is_turn", false);
		
			gameExtension.send(BaseCommandDefinition.responseCreateBoard, resObj, userList.get(i));
		}
	}
	
	private void moveItem(User sender, ISFSObject params){
		Board board = boards.get(1);
		
		boolean status = board.moveItem(params.getInt("row"), params.getInt("column"), params.getInt("newRow"), params.getInt("newColumn"));
		
		ISFSObject resObj = SFSObject.newInstance();
		resObj.putBool("status", status);
		
		resObj.putInt("row", params.getInt("row"));
		resObj.putInt("column", params.getInt("column"));
		resObj.putInt("newRow", params.getInt("newRow"));
		resObj.putInt("newColumn", params.getInt("newColumn"));
		
		if(status)
		{
			resObj.putUtfString("itemListString", board.itemListToString());
			resObj.putUtfString("tmpItemListString", board.tmpItemListToString());
		}
		
		//gameExtension.send(BaseCommandDefinition.responseMoveItem, resObj, sender);
		
		// VH TEST
		// Trường hợp move item ko có kết quả status = false
		Room room = sender.getLastJoinedRoom();
		List<User> userList = room.getPlayersList();
		for(int i=0; i < userList.size(); i++)
		{
			if(userList.get(i) == sender)	// User playing
			{
				resObj.putBool("is_playing", true);
				
				gameExtension.send(BaseCommandDefinition.responseMoveItem, resObj, userList.get(i));
			}
			else
			{
				if(status)
				{
					resObj.putBool("is_playing", false);
					gameExtension.send(BaseCommandDefinition.responseMoveItem, resObj, userList.get(i));
				}
			}
		}
	}
	
	private void checkAllItems(User sender, ISFSObject params){
		Board board = boards.get(1);
		
		boolean status = board.checkAllItems();
		
		ISFSObject resObj = SFSObject.newInstance();
		resObj.putBool("status", status);
		
		if(status)
		{
			resObj.putUtfString("itemListString", board.itemListToString());
			resObj.putUtfString("tmpItemListString", board.tmpItemListToString());
		}
		
		//gameExtension.send(BaseCommandDefinition.responseCheckAllItems, resObj, sender);
		
		// VH TEST
		Room room = sender.getLastJoinedRoom();
		List<User> userList = room.getPlayersList();
		for(int i=0; i < userList.size(); i++)
		{
			if(userList.get(i) == sender)	// User playing
			{
				resObj.putBool("is_playing", true);
			}
			else
			{
				resObj.putBool("is_playing", false);
			}
		
			gameExtension.send(BaseCommandDefinition.responseCheckAllItems, resObj, userList.get(i));
		}
	}
	
	public void destroy(){
		this.gameExtension = null;
		this.currentZone = null;
	}
}
